package jaas;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

public class MyMVCLoginModule implements LoginModule
{	
	  private Subject subject = null;
	  private Set principals = null;
	  private CallbackHandler callbackHandler = null;
	  private Map sharedState = null;
	  private Map options = null;
	  private boolean succeeded = false;
	  private boolean commitSucceeded = false;
	  private MyPrincipal principal = new MyPrincipal("MyMVCLoginModule");
	  private MyGroup roles = null;
	  private MyGroup callerPrincipal = null;
	  
	  
	@Override
	public boolean abort()
	  throws LoginException
	  {
	    boolean ret = true;
	    succeeded = false;
	    if (commitSucceeded)
	    {
	      ret = ret && logout();
	      commitSucceeded = false;
	    }
	    System.out.println("HelloWorldLoginModule.abort(): "+ret);
	    return ret;
	  }

	@Override
	public boolean commit()
	  throws LoginException
	  {
	    boolean ret = false;
	    if (succeeded)
	    {
	      principals.add(principal);
	      principals.add(roles);
	      principals.add(callerPrincipal);
	      System.out.println(subject);
	      ret = commitSucceeded = true;
	    }
	    System.out.println("HelloWorldLoginModule.commit(): "+ret);
	    return ret;
	  }
	@Override
	public void initialize(Subject newSubject, CallbackHandler cbh, 
			Map newSharedState , Map newOptions) 
	{
		subject = newSubject;
		principals = subject.getPrincipals();
		callbackHandler = cbh;
		sharedState = newSharedState;
		options = newOptions;
	}
	@Override
	public boolean login() throws LoginException 
	{
		boolean ret = false;
		NameCallback nc = new NameCallback("user name: ", "guest");
		PasswordCallback pc = new PasswordCallback("Password: ", false);
		Callback callbacks[] = {nc, pc };
		try
		{
			callbackHandler.handle(callbacks);
		}
		catch(IOException e)
		{
			System.out.println(e);
			LoginException le = new LoginException("Failed to get username/password");
			le.initCause(e);
			throw le;
		} catch (UnsupportedCallbackException e) {
			System.out.println(e);
		      LoginException le = new LoginException("CallbackHandler does not support: " + e.getCallback());
		      le.initCause(e);
		      throw le;
		}
		String username = nc.getName();
		char[] pwd = pc.getPassword();
		String password = new String((char[])pwd.clone());
		pc.clearPassword();
		System.out.println("Username: " +username);
		System.out.println("Password: " +password);
		if(username.equals("jesse") && password.equals("gorter"))
		{
			roles = new MyGroup("Roles");
			roles.addMember(new MyPrincipal("beheerders"));
			callerPrincipal = new MyGroup("CallerPrincipal");
			callerPrincipal.addMember(new MyPrincipal(username));
			ret = succeeded = true;
		}
		System.out.println("HelloWorldLoginModule.login(): "+ret);
	    return ret;
		
	}
	@Override
	  public boolean logout()
	  throws LoginException
	  {
	    boolean ret = principals.remove(principal);
	    ret = ret && principals.remove(roles);
	    ret = ret && principals.remove(callerPrincipal);
	    System.out.println("HelloWorldLoginModule.logout(): "+ret);
	    return ret;
	  }

	 
	  
	  
}
